package com.starhub.application.collection.service.impl;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.hadoop.thirdparty.org.checkerframework.checker.units.qual.s;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.starhub.application.collection.client.LinkDataClient;
import com.starhub.application.collection.dto.DataManipulationDto;
import com.starhub.application.collection.dto.MetaDataLinkDto;
import com.starhub.application.collection.dto.MetaDataSimpleData;
import com.starhub.application.collection.entity.KnowledgeBase;
import com.starhub.application.collection.entity.KnowledgeCollection;
import com.starhub.application.collection.entity.MetadataRelation;
import com.starhub.application.collection.mapper.MetadataRelationMapper;
import com.starhub.application.collection.service.CollectionService;
import com.starhub.application.collection.service.DataManipulationService;
import com.starhub.application.collection.service.KnowledgeBaseService;
import com.starhub.application.collection.service.KnowledgeCollectionService;
import com.starhub.utils.Util;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

/**
 * 数据操作服务实现类
 * 
 * @version: V1.0
 * @author: liuhf
 * @time 2025-06-06
 */
@Slf4j
@Service
public class DataManipulationServiceImpl extends CollectionService implements DataManipulationService {

    @Autowired
    private KnowledgeBaseService knowledgeBaseService;

    @Autowired
    private KnowledgeCollectionService knowledgeCollectionService;

    @Autowired
    private LinkDataClient linkDataClient;

    @Autowired
    private MetadataRelationMapper metadataRelationMapper;

    /**
     * 检查知识库表参数
     * 
     * @param dataManipulationDto
     */
    private void checkBaseParams(DataManipulationDto dataManipulationDto) {
        KnowledgeBase knowledgeBase = knowledgeBaseService
                .selectByIdAndNotDeleted(Util.getLongValue(dataManipulationDto.getBaseId()));
        KnowledgeCollection knowledgeCollection = knowledgeCollectionService
                .selectByIdAndNotDeleted(Util.getLongValue(dataManipulationDto.getCollectionId()));
        if (knowledgeBase == null) {
            throw new RuntimeException("知识库表不存在");
        }
        if (knowledgeCollection == null) {
            throw new RuntimeException("知识库表不存在");
        }
        dataManipulationDto.setKnowledgeBase(knowledgeBase);
        dataManipulationDto.setKnowledgeCollection(knowledgeCollection);
    }

    /**
     * 保存数据
     * 
     * @param dataManipulationDto
     * @return
     */
    @Override
    public String saveData(DataManipulationDto dataManipulationDto) {
        // 获取知识库表
        checkBaseParams(dataManipulationDto);
        return this.getClient(dataManipulationDto.getKnowledgeCollection().getBusinessType())
                .saveData(dataManipulationDto);
    }

    /**
     * 更新数据
     * 
     * @param dataManipulationDto
     * @return
     */
    @Override
    public boolean updateData(DataManipulationDto dataManipulationDto) {
        // 获取知识库表
        checkBaseParams(dataManipulationDto);
        return this.getClient(dataManipulationDto.getKnowledgeCollection().getBusinessType())
                .updateData(dataManipulationDto);
    }

    /**
     * 删除数据
     * 
     * @param dataManipulationDto
     * @return
     */
    @Override
    public boolean deleteData(DataManipulationDto dataManipulationDto) {
        // 获取知识库表
        checkBaseParams(dataManipulationDto);
        return this.getClient(dataManipulationDto.getKnowledgeCollection().getBusinessType())
                .deleteData(dataManipulationDto);
    }

    /**
     * 添加目标链接数据
     */
    @Override
    public boolean addTargetLinkData(MetaDataLinkDto MetaDataLinkDto) {
        try {
            checkMetaDataLinkDto(MetaDataLinkDto);
            return linkDataClient.addTargetLinkData(MetaDataLinkDto);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("添加目标链接数据失败: {}", e.getMessage());
            throw new RuntimeException("添加目标链接数据失败: " + e.getMessage(), e);
        }
    }

    /**
     * 更新目标链接数据
     */
    @Override
    public boolean updateTargetLinkData(MetaDataLinkDto MetaDataLinkDto) {
        try {
            checkMetaDataLinkDto(MetaDataLinkDto);
            return linkDataClient.updateTargetLinkData(MetaDataLinkDto);
        } catch (Exception e) {
            log.error("更新目标链接数据失败: {}", e.getMessage());
            throw new RuntimeException("更新目标链接数据失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除目标链接数据
     */
    @Override
    public boolean removeTargetLinkData(MetaDataLinkDto MetaDataLinkDto) {
        try {
            checkMetaDataLinkDto(MetaDataLinkDto);
            return linkDataClient.removeTargetLinkData(MetaDataLinkDto);
        } catch (Exception e) {
            log.error("删除目标链接数据失败: {}", e.getMessage());
            throw new RuntimeException("删除目标链接数据失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除所有目标链接数据
     */
    @Override
    public boolean removeAllTargetLinkData(MetaDataLinkDto MetaDataLinkDto) {
        try {
            checkMetaDataLinkDto(MetaDataLinkDto);
            return linkDataClient.removeAllTargetLinkData(MetaDataLinkDto);
        } catch (Exception e) {
            log.error("删除所有目标链接数据失败: {}", e.getMessage());
            throw new RuntimeException("删除所有目标链接数据失败: " + e.getMessage(), e);
        }
    }

    /**
     * 根据元数据ID获取主数据ID
     * @param mainCollectionId
     * @param metaCollectionId
     * @param itemIds
     * @return
     */
    @Override
    public List<String> getMainDatas(String mainCollectionId, String metaCollectionId, List<String> itemIds) {
        List<String> mainIds = metadataRelationMapper.selectList(new LambdaQueryWrapper<MetadataRelation>()
                .in(MetadataRelation::getMetaDataId, itemIds)
                .eq(MetadataRelation::getMainCollectionId, mainCollectionId)
                .eq(MetadataRelation::getMetaCollectionId, metaCollectionId))
                .stream()
                .map(MetadataRelation::getMainDataId)
                .collect(Collectors.toList());

        return mainIds;
    }

    /**
     * 参数补全
     * 
     * @param metaDataLinkDto
     */
    private void checkMetaDataLinkDto(MetaDataLinkDto metaDataLinkDto) {
        KnowledgeCollection knowledgeCollection = knowledgeCollectionService
                .selectByIdAndNotDeleted(Util.getLongValue(metaDataLinkDto.getCollectionId()));
        if (knowledgeCollection == null) {
            throw new RuntimeException("知识库表不存在");
        }

        KnowledgeCollection metaKnowledgeCollection = knowledgeCollectionService
                .selectByIdAndNotDeleted(Util.getLongValue(metaDataLinkDto.getMetaCollectionId()));
        if (metaKnowledgeCollection == null) {
            throw new RuntimeException("元数据知识库表不存在");
        }

        // 创建MetaDataSimpleData列表
        if (metaDataLinkDto.getSelectIds() != null && !metaDataLinkDto.getSelectIds().isEmpty()) {
            List<MetaDataSimpleData> metaDataList = metaDataLinkDto.getSelectIds().stream()
                    .map(id -> MetaDataSimpleData.builder()
                            .id(id)
                            .collectionId(metaDataLinkDto.getMetaCollectionId())
                            .build())
                    .collect(Collectors.toList());

            metaDataLinkDto.setMetaDatas(metaDataList);
        }
        metaDataLinkDto.setCollectionIdentifier(knowledgeCollection.getCollectionIdentifier());
        metaDataLinkDto.setMetaCollectionIdentifier(metaKnowledgeCollection.getCollectionIdentifier());
    }

    // TODO 知识库的前端交互页面（知识库本身的功能，数据标准平台相关的功能） 现成的效果图或者其他的系统，确认下展现形式
    // TODO 新增条目时，自动关联元数据的功能（含智能体） 每个元数据需要定一个抽取规则（多个提示词片段） 完整的元数据提取提示词=（固定模板+动态片段）
    // 函数/json模拟的方式 跟数据标注平台的操作效果相互对应
    // TODO
    // 智能体内根据所属场景和提示词，进行检索和召回（用户的输入数据，查找对应的元数据，再根据元数据定位主数据，最后把匹配到的元数据和主数据拼接成一个新的提示词，交给大模型写作）
    // TODO rag检索和召回了一部分有效的数据，模拟这个结果的最终提示词，交给一个大模型去生成，比较一下是否有提高
}
